package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itheima.domain.mongo.*;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@DubboService
public class MovementServiceImp implements MovementService {
    @Autowired
    private RedisIDService redisIDService;
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override//发布动态
    public void saveMovement(Movement movement) {
        //使用redis自增器给动态类中pid赋值
        Long pid = redisIDService.getNextId(ConstantUtil.MOVEMENT_ID);
        movement.setPid(pid);
        //调用mongo给表中添加信息
        mongoTemplate.save(movement);
        //获取动态主键id
        ObjectId publishId = movement.getId();
        //创建我的动态类
        MyMovement myMovement = new MyMovement();
        //赋值动态创建时间
        myMovement.setCreated(movement.getCreated());
        //赋值动态的主键id
        myMovement.setPublishId(publishId);
        //调用mongo添加我的动态信息
        mongoTemplate.save(myMovement, ConstantUtil.MOVEMENT_MINE + movement.getUserId());
        //创建条件为userId列内容为动态中的userId
        Query query = Query.query(Criteria.where("userId").is(movement.getUserId()));
        //在我的好友列表中查询返回集合
        List<Friend> friends = mongoTemplate.find(query, Friend.class);
        //判断非空
        if (CollectionUtil.isNotEmpty(friends)) {
            //遍历好友信息
            for (Friend friend : friends) {
                //获取好友id
                Long friendId = friend.getFriendId();
                //创建好友动态类
                FriendMovement friendMovement = new FriendMovement();
                //赋值
                friendMovement.setUserId(movement.getUserId());
                friendMovement.setCreated(movement.getCreated());
                friendMovement.setPublishId(publishId);
                //使用mongo添加好友动态信息
                mongoTemplate.save(friendMovement, ConstantUtil.MOVEMENT_FRIEND + friendId);
            }
        }

    }

    @Override//查看我的动态
    public PageBeanVo findMyMovement(Long userId, Integer pageNum, Integer pageSize) {
        //获取分页开始索引
        Integer index = (pageNum - 1) * pageSize;
        //创建条件为创建时间降序并分页
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip(index).limit(pageSize);
        //使用mongo查询 返回我的动态集合
        List<MyMovement> myMovements = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        //我的详细动态集合
        List list = new ArrayList();
        //判断我的动态非空
        if (CollectionUtil.isNotEmpty(myMovements)) {
            //遍历集合
            for (MyMovement myMovement : myMovements) {
                //根据我的动态中的动态主键id查询出详细动态类
                Movement movement = mongoTemplate.findById(myMovement.getPublishId(), Movement.class);
                //判断动态审核状态为已审核
                if (movement.getState() == 1) {
                    //把动态添加到我的详细动态集合
                    list.add(movement);
                }
            }
        }
        //获取我的动态总数
        long count = mongoTemplate.count(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        //创建自定义分页类赋值并返回
        return new PageBeanVo(pageNum, pageSize, count, list);
    }

    @Override//查询好友动态
    public PageBeanVo findFriendMovement(Long userId, Integer pageNum, Integer pageSize) {
        //计算分页开始索引
        Integer index = (pageNum - 1) * pageSize;
        //创建条件为创建时间详细并分页
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip(index).limit(pageSize);
        //查询好友动态集合
        List<FriendMovement> friendMovements = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);
        //好友详细动态集合
        List list = new ArrayList();
        //判断好友动态集合非空
        if (CollectionUtil.isNotEmpty(friendMovements)) {
            //遍历集合
            for (FriendMovement friendMovement : friendMovements) {
                //根据好友动态中的动态主键id查询详细动态类
                Movement movement = mongoTemplate.findById(friendMovement.getPublishId(), Movement.class);
                //判断动态审核状态为已审核
                if (movement.getState() == 1) {
                    //把动态添加到好友详细动态集合
                    list.add(movement);
                }
            }
        }
        //获取好友动态总条数
        long count = mongoTemplate.count(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);
        //创建自定义分页类赋值并返回
        return new PageBeanVo(pageNum, pageSize, count, list);
    }

    @Override//findRecommendMovement
    public PageBeanVo findRecommendMovement(Long userId, Integer pageNum, Integer pageSize) {
        //计算分页开始索引
        Integer index = (pageNum - 1) * pageSize;
        //创建条件为userId相等 按照分数降序 并分页
        Query query = new Query(Criteria.where("userId").is(userId))
                .with(Sort.by(Sort.Order.desc("score")))
                .skip(index).limit(pageSize);
        //调用mongo查询满足条件的推荐动态
        List<RecommendMovement> recommendMovements = mongoTemplate.find(query, RecommendMovement.class);
        //创建动态详情集合
        List<Movement> list = new ArrayList<>();
        //判断非空 遍历
        if (CollectionUtil.isNotEmpty(recommendMovements)) {
            for (RecommendMovement recommendMovement : recommendMovements) {
                //根据推荐动态中的动态id获取动态详情
                Movement movement = mongoTemplate.findById(recommendMovement.getPublishId(), Movement.class);
                //判断如果动态为已审核
                if (movement.getState() == 1) {
                    //添加到动态详情集合
                    list.add(movement);
                }
            }
        }
        //调用mongo获取推荐动态数量
        long count = mongoTemplate.count(query, RecommendMovement.class);
        //返回分页类
        return new PageBeanVo(pageNum, pageSize, count, list);
    }

    @Override//根据动态id查询动态详情
    public Movement findById(ObjectId publishId) {
        return mongoTemplate.findById(publishId, Movement.class);
    }

    @Override //查询动态分页
    public PageBeanVo findMovementVoByPage(Long userId, Integer state, Integer pageNum, Integer pageSize) {
        //创建分页并根据创建时间降序条件
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize).limit(pageSize);
        //如果用户id不为空 添加用户id字段条件
        if (userId != null) {
            query.addCriteria(Criteria.where("userId").is(userId));
        }
        //如果审核状态不为空 添加审核状态字段条件
        if (state != null) {
            query.addCriteria(Criteria.where("state").is(state));
        }
        //调用mongo查询动态集合
        List<Movement> movements = mongoTemplate.find(query, Movement.class);
        //调用mongo查询满足条件的动态数量
        Long counts = mongoTemplate.count(query, Movement.class);
        //创建分页类 赋值并返回
        return new PageBeanVo(pageNum, pageSize, counts, movements);
    }

    @Override//根据动态id更新动态详情
    public void updateMovementById(Movement movement) {
        mongoTemplate.save(movement);
    }

}
